package net.bezrabotnih.server.domain;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PersistenceContext;
import javax.persistence.Transient;
import javax.persistence.Version;

import org.datanucleus.jpa.annotations.Extension;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


@Entity
@Configurable
public class Application {
	
	@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
	@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
	private String id;
	
	@Version
	@Column(name = "version")
	private Integer version;
	
	
	private String jobId;
	
	
	private String userAccountId;
	
	
	private Date created=new Date();
	
	@Transient
	private UserAccount userAccount;
	
	
	public UserAccount getUserAccount() {
    	if (this.userAccountId != null) {
            if (userAccount == null || userAccount.getId() != this.userAccountId) {
            	userAccount = UserAccount.findUserAccount(this.userAccountId);
            }
        } else {
        	userAccount = null;
        }
        return userAccount;
    }
	
	
	@SuppressWarnings("unchecked")
	public static  List<Application> findApplicationsAmongAppliedBy(List<String> jobIds,String userAccountId){
		
		 return entityManager().createQuery("SELECT o FROM Application o WHERE o.jobId MEMBER OF :jobIds AND o.userAccountId=:userAccountId ORDER BY o.created ASC").setParameter("jobIds", jobIds).setParameter("userAccountId", userAccountId).getResultList();
		
		
	}
	
	
	 @Transactional(propagation = Propagation.REQUIRES_NEW)
	    public void persist() {
	        if (this.entityManager == null) this.entityManager = entityManager();
	        
	        long count=countApplications(jobId, userAccountId);
//	        System.out.println("count="+count);
	        if (count>1){
	        	deleteApplications(jobId, userAccountId);
	        }else if (count==1) return;
	        System.out.println("userAccountId="+userAccountId);
	        this.entityManager.persist(this);
	    }
	    
	    @Transactional
	    public void remove() {
	        if (this.entityManager == null) this.entityManager = entityManager();
	        if (this.entityManager.contains(this)) {
	            this.entityManager.remove(this);
	        } else {
	            Application attached = findApplication(this.id);
	            this.entityManager.remove(attached);
	        }
	    }
	    
	    @Transactional
	    public void flush() {
	        if (this.entityManager == null) this.entityManager = entityManager();
	        this.entityManager.flush();
	    }
	    
	    @Transactional
	    public void clear() {
	        if (this.entityManager == null) this.entityManager = entityManager();
	        this.entityManager.clear();
	    }
	    
	    @Transactional
	    public Application merge() {
	        if (this.entityManager == null) this.entityManager = entityManager();
	        Application merged = this.entityManager.merge(this);
	        this.entityManager.flush();
	        return merged;
	    }
	    
	    public static final EntityManager entityManager() {
	        EntityManager em = new Application().entityManager;
	        if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
	        return em;
	    }
	    
	    
	    @SuppressWarnings("unchecked")
	    @Transactional
	    public static List<Application> findApplicationsByJobId(String jobId) {
	        return entityManager().createQuery("SELECT o FROM Application o WHERE o.jobId=:id  ORDER BY o.created ASC").setParameter("id", jobId).getResultList();
	    }
	
	    @Transactional
	    public static long countApplications(String jobId,String userAccountId) {
//	    	System.out.println("count applications");
	        return ((Number) entityManager().createQuery("SELECT COUNT(o) FROM Application o WHERE o.jobId=:jobId AND o.userAccountId=:userAccountId").setParameter("jobId", jobId).setParameter("userAccountId", userAccountId).getSingleResult()).longValue();
	    }
	    
	    @Transactional
	    public static void deleteApplications(String jobId,String userAccountId) {
	        entityManager().createQuery("DELETE FROM Application o WHERE o.jobId=:jobId AND o.userAccountId:=userAccountId").setParameter("jobId", jobId).setParameter("userAccountId", userAccountId);
	    }
	
	    @Transactional
	    public static Application findApplication(String id) {
	        if (id == null || id.length() == 0) return null;
	        try {
	            return (Application) entityManager().createQuery("SELECT o FROM Application o WHERE o.id = :id").setParameter("id", id).getSingleResult();
	        } catch (org.springframework.dao.EmptyResultDataAccessException e) {
	            return null;
	        } catch (javax.persistence.NoResultException e) {
	            return null;
	        }
	    }
	
	
	
	
	 public String getId() {
		return id;
	}





	public void setId(String id) {
		this.id = id;
	}





	public Integer getVersion() {
		return version;
	}





	public void setVersion(Integer version) {
		this.version = version;
	}





	public String getJobId() {
		return jobId;
	}





	public void setJobId(String jobId) {
		this.jobId = jobId;
	}





	public String getUserAccountId() {
		return userAccountId;
	}





	public void setUserAccountId(String userAccountId) {
		this.userAccountId = userAccountId;
	}





	public Date getCreated() {
		return created;
	}


	public void setCreated(Date created) {
		this.created = created;
	}





	@PersistenceContext
	 transient EntityManager entityManager;
	 
	 
	 
	
	

}
